package com.htu.courseService.exam.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.htu.courseService.common.enums.RedisCachePrefix;
import com.htu.courseService.common.util.UserUtil;
import com.htu.courseService.exam.dao.AnswerMapper;
import com.htu.courseService.exam.dao.AnswerSheetMapper;
import com.htu.courseService.exam.dao.ExamMapper;
import com.htu.courseService.exam.dao.QuestionMapper;
import com.htu.courseService.exam.entity.Answer;
import com.htu.courseService.exam.entity.AnswerSheet;
import com.htu.courseService.exam.entity.Exam;
import com.htu.courseService.exam.entity.Question;
import com.htu.courseService.exam.service.ExamService;
import com.htu.courseService.exam.vo.*;
import com.htu.courseService.user.vo.UserInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

@Service
@RequiredArgsConstructor
@Slf4j
public class ExamServiceImpl implements RedisCachePrefix, ExamService {
    private final ExamMapper examMapper;
    private final QuestionMapper questionMapper;
    private final AnswerSheetMapper answerSheetMapper;
    private final AnswerMapper answerMapper;
    @Override
    public void submitExam(ExamDto examDto) {
        UserInfo userInfo = UserUtil.getUserInfo();
        Exam exam = new Exam();
        exam.setCourseId(examDto.getCourseId());
        exam.setExamTitle(examDto.getExamTitle());
        exam.setDescription(examDto.getDescription());
        exam.setCreatedAt(new Date());
        exam.setCreatedBy(userInfo.getId());
        examMapper.insert(exam);
        List<QuestionDto> questionDtoList = examDto.getQuestions();
        List<Question> list = new ArrayList<>();
        int sort = 1;
        if(!questionDtoList.isEmpty()){
            for(QuestionDto questionDto : questionDtoList){
                Question question = BeanUtil.copyProperties(questionDto,Question.class);
                question.setExamId(exam.getExamId());
                String option;
                try {
                    option = getStringToMap("option",questionDto.getOptions());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                question.setSort(sort);
                question.setOptions(option);//选项是json格式
                sort++;
                list.add(question);
            }
            questionMapper.insert(list);
        }
    }

    private String getStringToMap(String type,String info) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        //将前端传过来的用，分割开的，转化为json存储到数据库中
        List<Map<String,String>> mapList = new ArrayList<>();
        List<String> result = Arrays.asList(info.split("，"));
        if(!result.isEmpty()){
            for(String res : result){
                Map<String, String> mapOne = new HashMap<>();
                mapOne.put(type,res);
                mapList.add(mapOne);
            }
        }
        String json = objectMapper.writeValueAsString(mapList);
        return json;
    }

    private String getStringToMapAnswer(String type,String info) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        //将前端传过来的用，分割开的，转化为json存储到数据库中
        List<Map<String,String>> mapList = new ArrayList<>();
        List<String> result = Arrays.asList(info.split(","));
        if(!result.isEmpty()){
            for(String res : result){
                Map<String, String> mapOne = new HashMap<>();
                mapOne.put(type,res);
                mapList.add(mapOne);
            }
        }
        String json = objectMapper.writeValueAsString(mapList);
        return json;
    }

    @Override
    public IPage<ExamInfoDto> pageInfo(ExamQuery examQuery) {
        IPage<Exam> page = new Page<>(examQuery.getPageNum(),examQuery.getPageSize());
        IPage<ExamInfoDto> examInfoDtoIPage = examMapper.getExamInfo(page,examQuery.getExamTitle(),
                examQuery.getNickName());
        return examInfoDtoIPage;
    }

    @Override
    public ExamDto getExamDetail(Integer examId) {
        ExamDto examDto = examMapper.selectDetail(examId);
        LambdaQueryWrapper<Question> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Question::getExamId,examId);
        List<Question> questionList = questionMapper.selectList(wrapper);
        List<QuestionDto> questionDtoList = new ArrayList<>();
        if(!questionList.isEmpty()){
            questionList.forEach(i -> {
                i.setContent(i.getSort() + ". " + i.getContent() + "（分值：" + i.getQuestionScore() + "分）");
                QuestionDto questionDto = BeanUtil.copyProperties(i, QuestionDto.class);
                questionDto.setQuestionId(i.getId());
                questionDtoList.add(questionDto);
            });
        }
        examDto.setQuestions(questionDtoList);
        return examDto;
    }

    @Override
    public IPage<ExamInfoDto> getMyPageInfo(ExamQuery examQuery) {
        UserInfo userInfo = UserUtil.getUserInfo();
        IPage<Exam> page = new Page<>(examQuery.getPageNum(),examQuery.getPageSize());
        IPage<ExamInfoDto> examInfoDtoIPage = examMapper.getMyExamInfo(page,examQuery.getExamTitle(),
                examQuery.getNickName(),userInfo.getId());
        return examInfoDtoIPage;
    }

    @Override
    public void submitExamDetail(AnswerDto answerDto) {
        UserInfo userInfo = UserUtil.getUserInfo();
        Integer examId = answerDto.getExamId();
        AnswerSheet answerSheet = new AnswerSheet();
        answerSheet.setExamId(examId);
        answerSheet.setCreated_at(new Date());
        answerSheet.setCreated_by(userInfo.getId());
        answerSheetMapper.insert(answerSheet);
        List<AnswerInfoDto> dtoList = answerDto.getAnswerList();
        List<Answer> answerList = new ArrayList<>();
        if(!dtoList.isEmpty()){
            dtoList.forEach(i -> {
                Answer answer = BeanUtil.copyProperties(i,Answer.class);
                Question question = questionMapper.selectById(i.getQuestionId());
                String questionAnswer = question.getAnswer();
                String type = question.getQuestionType();
                Double questionScore = question.getQuestionScore();
                answer.setAnswerSheetId(answerSheet.getId());
                if("judgment".equals(type) || "single".equals(type)){//判断题
                    if(null != i.getAnswer()){
                        if(i.getAnswer().equals(questionAnswer)){
                            answer.setScore(questionScore);
                        }else {
                            answer.setScore(0d);
                        }
                    }else {
                        answer.setScore(0d);
                    }
                } else if("multiple".equals(type) && null != answer.getAnswer()){
                    List<String> userAnswer = List.of(answer.getAnswer().split(","));
                    List<String> correctAnswer = List.of(questionAnswer.split(","));
                    Set<String> setOne = new HashSet<>(userAnswer);
                    Set<String> setTwo = new HashSet<>(correctAnswer);
                    if(setOne.equals(setTwo)){
                        answer.setScore(questionScore);
                    }else {
                        if(userAnswer.stream().anyMatch(correctAnswer::contains)){
                            answer.setScore(questionScore/2);
                        }else {
                            answer.setScore(0d);
                        }
                    }
                }else {
                    answer.setScore(0d);
                }
                answerList.add(answer);
            });
            answerMapper.insert(answerList);
        }
    }

    @Override
    public ExamDto getMyExamDetail(Integer examId) {
        UserInfo userInfo = UserUtil.getUserInfo();
        LambdaQueryWrapper<AnswerSheet> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AnswerSheet::getExamId,examId);
        wrapper.eq(AnswerSheet::getCreated_by,userInfo.getId());
        AnswerSheet answerSheet = answerSheetMapper.selectOne(wrapper);
        ExamDto examDto = examMapper.getMyExamDetail(examId);
        List<QuestionDto> questionDtoList = new ArrayList<>();
        if(null == answerSheet){//说明这个人没有答题
            examDto.setIfExam("0");
            LambdaQueryWrapper<Question> wrapperQ = new LambdaQueryWrapper<>();
            wrapperQ.eq(Question::getExamId,examId);
            List<Question> questionList = questionMapper.selectList(wrapperQ);
            if(!questionList.isEmpty()){
                questionList.forEach(i ->{
                    i.setContent(i.getSort() + ". " + i.getContent() + "（分值：" + i.getQuestionScore() + "分）");
                    QuestionDto questionDto = BeanUtil.copyProperties(i, QuestionDto.class);
                    questionDto.setQuestionId(i.getId());
                    questionDto.setAnswer(null);
                    questionDtoList.add(questionDto);
                });
            }
            examDto.setQuestions(questionDtoList);
        }else {//这个人答题了
            examDto.setIfExam("1");
            List<QuestionDto> questionDtoListExam = examMapper.getMyAnswerList(answerSheet.getId());
            BigDecimal allScore = new BigDecimal(0);
            if(!questionDtoListExam.isEmpty()){
                for(QuestionDto dto : questionDtoListExam){
                    allScore = allScore.add(new BigDecimal(Double.toString(dto.getMyScore())));
                }
            }
            examDto.setAllScore(allScore.doubleValue());
            examDto.setQuestions(questionDtoListExam);
        }
        return examDto;
    }
}
